﻿using System;
using System.Collections.Generic;
using System.Data.OleDb;
using System.Linq;
using System.Net;
using System.Text;
using System.Xml.XPath;

using System.IO;
using System.Data;

namespace ABC.Google
{

    public struct GeoCodeStruct
    {
        public string Latitude;
        public string Longitude;
        public string locationType;
        public long abcAddressID;
    }
    public struct currentTrips 
    {
        public string Latitude { get; set; }
        public string Longitude { get; set; }
        public System.DayOfWeek dayOfWeek { get; set; }
        public long invoice { get; set; }
        public DateTime tripDate { get; set; }
        public string imagePath { get; set; }
        public object tech { get; set; }
        public string category { get; set; }
        public string City { get; set; }
        public string Zip { get; set; }
        public string address { get; set; }
        public string state { get; set; }

      

        public string jobSize { get; set; }
    }
    public struct WOONsitePartsReceived
    {
        //public string Latitude;
        public string Longitude;
        public long invoice { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ContentDescription { get; set; }
        public string Zip { get; set; }
        public string address { get; set; }
        public string TAT { get; set; }

        public string Latitude { get; set; }

        public string BillToCode { get; set; }
        public string Brand { get; set; }
        public string Model { get; set; }
        public string RequestDate { get; set; }
        public string Tech { get; set; }
        public string BillCode { get; set; }
        public string CAT { get; set; }
        public string Dept { get; set; }
        public string LastName { get; set; }
        public string partsReceivedNotes { get; set; }
        public string MaxOfTripDate { get; set; }
        public string jobSize { get; set; }
        
    }
    public struct UnitsRequiringMoreInfo
    {
        public string Latitude { get; set; }
        public string Longitude { get; set; }
        public long invoice { get; set; }
        public string Address { get; set; }
        public string ZipCode { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ContentDescription { get; set; }
        public string TAT { get; set; }

        public string brand { get; set; }

        public string model { get; set; }

        public string researchRequestDate { get; set; }

        public string timeInQue { get; set; }

        public string researchTech { get; set; }

        public string dateAssignedToTech { get; set; }

        public string billCode { get; set; }

        public string status { get; set; }

        public string category { get; set; }

        public string shelf { get; set; }

        public string requestScheduledDate { get; set; }

        public string lastName { get; set; }

        public string department { get; set; }

        public string firstname { get; set; }

        public string notes { get; set; }

        public string BillToCompany { get; set; }

        public string jobSize { get; set; }

        public string receivedate { get; set; }
    }
    public struct PartsIn7orLessDays
    {
        public string Latitude;
        public string Longitude;
        public long invoice;
        public string Address;
        public string ZipCode;
        public string City;
        public string State;
        public string ContentDescription;
        public string TAT;
    }
    public struct DealerPickUpRequest
    {
        public string Latitude;
        public string Longitude;
        public string Dealername;
        public string Address;
        public string ZipCode;
        public string City;
        public string State;
        public string ContentDescription;
        public DateTime tripDate;
        public string tech;
        public string imagePath;
        public string note;

    }
    public struct ShoppedUnit
    {

    }

    public static class Resources
    {
        public static Stream DownloadResource(string url)
        {
            MemoryStream stream = null;

            try
            {
                WebClient client = new WebClient();
                client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
                byte[] data = client.DownloadData(url);
                stream = new MemoryStream(data);
                client.Dispose();
            }
            catch (WebException )
            {
            }
            return stream;
        }
        public static DataTable DownloadXML(string url)
        {
            DataTable table = null;

            Stream stream = DownloadResource(url);
            DataSet ds = new DataSet();
            ds.ReadXml(stream);
            table = new DataTable();
            table.Columns.Add("Location");
            table.Columns.Add("Longitude");
            table.Columns.Add("Latitude");
            int iRow = 0;
            foreach (DataRow dr in ds.Tables["result"].Rows)
            {
                List<Object> objData = new List<Object>();
                objData.Add(dr[1].ToString().Trim());
                objData.Add(ds.Tables["location"].Rows[iRow][1].ToString().Trim());
                objData.Add(ds.Tables["location"].Rows[iRow][0].ToString().Trim());
                table.Rows.Add(objData.ToArray());
                iRow++;
            }
            ds.Dispose();
            stream.Close();
            stream.Dispose();

            return table;
        }
    }
    /// <summary>
    /// template to store methods for handling getting GeoCode Information
    /// </summary>
    public static class GeoCodes
    {
        public static DataTable AddressToLongitudeLatitude(string address)
        {
            DataTable table = null;
            // Get latitude-longitude for address
            string url = "http://maps.googleapis.com/maps/api/geocode/xml?address=";
            url += address;
            url += "&sensor=false";
            table = Resources.DownloadXML(url);
            return table;
        }
        
        /// <summary>
        /// Gets the Latitude and Longitude of a address. 
        /// </summary>
        /// <param name="fullAddress"></param>
        /// <returns></returns>
        public static GeoCodeStruct getGeoCode(string address)
        {
            GeoCodeStruct latAndLong = new GeoCodeStruct();
            WebResponse response = null;

            string fullAddress = "http://maps.googleapis.com/maps/api/geocode/xml?address=";
            fullAddress += address  + "&sensor=false";

            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(fullAddress);
                request.Method = "GET";
                response = request.GetResponse();
                if (response != null)
                {
                    XPathDocument document = new XPathDocument(response.GetResponseStream());
                    XPathNavigator navigator = document.CreateNavigator();
                    // get response status
                    XPathNodeIterator statusIterator = navigator.Select("/GeocodeResponse/status");
                    while (statusIterator.MoveNext())
                    {
                        if (statusIterator.Current.Value != "OK")
                        {
                            Console.WriteLine("Error: response status = '" + statusIterator.Current.Value + "'");
                            throw new GeoCodeLocationNotFoundException(statusIterator.Current.Value);
                        }
                    }
                    // get results
                    XPathNodeIterator resultIterator = navigator.Select("/GeocodeResponse/result");
                    while (resultIterator.MoveNext())
                    {
                        Console.WriteLine("Result: ");
                        XPathNodeIterator formattedAddressIterator = resultIterator.Current.Select("formatted_address");
                        while (formattedAddressIterator.MoveNext())
                        {
                            Console.WriteLine(" formatted_address: " + formattedAddressIterator.Current.Value);
                        }
                        XPathNodeIterator geometryIterator = resultIterator.Current.Select("geometry");
                        while (geometryIterator.MoveNext())
                        {
                            Console.WriteLine(" geometry: ");
                            XPathNodeIterator locationIterator = geometryIterator.Current.Select("location");
                            while (locationIterator.MoveNext())
                            {
                                Console.WriteLine("     location: ");

                                XPathNodeIterator latIterator = locationIterator.Current.Select("lat");
                                while (latIterator.MoveNext())
                                {
                                    Console.WriteLine("         lat: " + latIterator.Current.Value);
                                    latAndLong.Latitude = latIterator.Current.Value;
                                }

                                XPathNodeIterator lngIterator = locationIterator.Current.Select("lng");
                                while (lngIterator.MoveNext())
                                {
                                    Console.WriteLine("         lng: " + lngIterator.Current.Value);
                                    latAndLong.Longitude = lngIterator.Current.Value;
                                }
                            }

                            XPathNodeIterator locationTypeIterator = geometryIterator.Current.Select("location_type");
                            while (locationTypeIterator.MoveNext())
                            {
                                Console.WriteLine("         location_type: " + locationTypeIterator.Current.Value);
                                latAndLong.locationType = locationTypeIterator.Current.Value;
                            }
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                Console.WriteLine("Clean up");
                if (response != null)
                {
                    response.Close();
                    response = null;
                }
            }
            return latAndLong;
        }
        /// <summary>
        /// Can be called to get the GeoCode for a address and then add it to the database used by ABC.
        /// </summary>
        public static void setAddressGeoCode(string fullAddress, long addressID)
        {
            GeoCodeStruct geoInfo = getGeoCode(fullAddress);
            geoInfo.abcAddressID = addressID;
            addAddressGeoCode(geoInfo);
        }
        public static void addAddressGeoCode(GeoCodeStruct geoInfo)
        {
            OleDbCommand command = new OleDbCommand();
            command.Connection = ABC.Database.DataBaseConnection.MyConn;
            command.CommandText =
                "update tabADDRESS set LATITUDE = '" + geoInfo.Latitude + "', LONGITUDE = '" + geoInfo.Longitude + "' where CODE = " + geoInfo.abcAddressID;
            command.ExecuteNonQuery();

        }


    }
}
